from django.db import transaction
from django.utils import timezone
from .models import Game, GameRound, PlayerAction
from apps.decks.models import Deck, DeckCard
from apps.cards.models import Card
import random


class GameLogic:
    """游戏逻辑处理"""
    
    @staticmethod
    def start_game(game):
        """开始游戏"""
        # 检查游戏是否满员（AI游戏的player2为None但player2_deck不为None）
        if not game.is_full and not (game.player2 is None and game.player2_deck is not None):
            return False, "游戏未满员"
        
        # 如果游戏状态不是playing，设置为playing
        if game.status != 'playing':
            game.status = 'playing'
            game.save()
        
        # 检查是否已经有回合，如果没有则创建第一回合
        existing_rounds = game.rounds.count()
        if existing_rounds == 0:
            GameRound.objects.create(
                game=game,
                round_number=1
            )
        
        return True, "游戏开始"
    
    @staticmethod
    def play_card(game, player, card):
        """玩家出牌"""
        current_round = game.rounds.filter(is_finished=False).first()
        if not current_round:
            return False, "没有进行中的回合"
        
        
        # 检查玩家是否已经出过牌
        existing_action = PlayerAction.objects.filter(
            game=game,
            round=current_round,
            player=player,
            action_type='play_card'
        ).exists()
        
        if existing_action:
            return False, "您已经出过牌了"
        
        # 检查玩家卡组中是否有这张卡
        if player == game.player1:
            deck = game.player1_deck
        else:
            deck = game.player2_deck
        
        # 使用卡牌ID进行验证，确保是玩家卡组中的卡牌
        deck_card = deck.deck_cards.filter(card__id=card.id).first()
        if not deck_card:
            return False, "您的卡组中没有这张卡"
        
        # 记录玩家行动
        PlayerAction.objects.create(
            game=game,
            round=current_round,
            player=player,
            action_type='play_card',
            card=card
        )
        
        # 更新回合信息
        if player == game.player1:
            current_round.player1_card = card
        else:
            current_round.player2_card = card
        current_round.save()
        
        # 检查回合是否结束
        if current_round.player1_card and current_round.player2_card:
            GameLogic.finish_round(current_round)
        
        return True, "出牌成功"
    
    @staticmethod
    def finish_round(round_obj):
        """结束回合并结算"""
        if not round_obj.player1_card or not round_obj.player2_card:
            return False, "回合未完成"
        
        # 使用新的结算逻辑
        winner = GameLogic.calculate_round_winner(round_obj)
        round_obj.winner = winner
        
        round_obj.is_finished = True
        round_obj.save()
        
        # 检查游戏是否结束
        GameLogic.check_game_end(round_obj.game)
        
        return True, "回合结束"
    
    @staticmethod
    def calculate_round_winner(round_obj):
        """计算回合获胜者"""
        player1_card = round_obj.player1_card
        player2_card = round_obj.player2_card
        game = round_obj.game
        
        # 预留空间：应用卡牌效果
        # TODO: 在这里应用各种卡牌效果，如被动效果、支援效果等
        # player1_card, player2_card = GameLogic.apply_card_effects(round_obj)
        
        # 1. 比较星级
        star_winner = GameLogic.compare_star_levels(player1_card, player2_card)
        if star_winner is not None:
            return GameLogic.convert_card_to_player(star_winner, game)
        
        # 2. 星级相同时，比较属性
        element_winner = GameLogic.compare_elements(player1_card, player2_card)
        if element_winner is not None:
            return GameLogic.convert_card_to_player(element_winner, game)
        
        # 3. 属性相同时，比较攻击力
        attack_winner = GameLogic.compare_attack_power(player1_card, player2_card)
        if attack_winner is not None:
            return GameLogic.convert_card_to_player(attack_winner, game)
        
        # 4. 攻击力相同时，当前回合玩家获胜（AI对战时AI获胜）
        return GameLogic.get_current_turn_winner(game)
    
    @staticmethod
    def compare_star_levels(player1_card, player2_card):
        """比较星级"""
        # 预留空间：应用星级相关的卡牌效果
        # TODO: 在这里应用星级相关的卡牌效果
        
        star1 = player1_card.star_level
        star2 = player2_card.star_level
        
        # 特殊规则：1星卡牌对抗5星或5星以上卡牌时获胜
        if star1 == 1 and star2 >= 5:
            return player1_card  # 返回卡牌对象，后续会转换为玩家
        elif star2 == 1 and star1 >= 5:
            return player2_card
        
        # 普通星级比较
        if star1 > star2:
            return player1_card
        elif star2 > star1:
            return player2_card
        
        return None  # 星级相同
    
    @staticmethod
    def compare_elements(player1_card, player2_card):
        """比较属性（五行相克）"""
        # 预留空间：应用属性相关的卡牌效果
        # TODO: 在这里应用属性相关的卡牌效果
        
        element1 = player1_card.element
        element2 = player2_card.element
        
        # 五行相克关系：金克木，木克土，土克水，水克火，火克金
        element_cycle = {
            'metal': 'wood',    # 金克木
            'wood': 'earth',    # 木克土
            'earth': 'water',   # 土克水
            'water': 'fire',    # 水克火
            'fire': 'metal'     # 火克金
        }
        
        # 检查相克关系
        if element_cycle.get(element1) == element2:
            return player1_card  # player1的属性克制player2
        elif element_cycle.get(element2) == element1:
            return player2_card  # player2的属性克制player1
        
        return None  # 属性不相克
    
    @staticmethod
    def compare_attack_power(player1_card, player2_card):
        """比较攻击力"""
        # 预留空间：应用攻击力相关的卡牌效果
        # TODO: 在这里应用攻击力相关的卡牌效果
        
        attack1 = player1_card.attack_power
        attack2 = player2_card.attack_power
        
        if attack1 > attack2:
            return player1_card
        elif attack2 > attack1:
            return player2_card
        
        return None  # 攻击力相同
    
    @staticmethod
    def convert_card_to_player(winning_card, game):
        """将获胜卡牌转换为对应的玩家"""
        # 获取当前回合
        current_round = game.rounds.filter(is_finished=False).first()
        if not current_round:
            # 如果没有未完成的回合，获取最近完成的回合
            current_round = game.rounds.filter(is_finished=True).order_by('-round_number').first()
        
        if winning_card == current_round.player1_card:
            return game.player1
        else:
            # AI对战时，AI获胜返回None
            if game.player2 is None and game.player2_deck is not None:
                return None
            else:
                return game.player2
    
    @staticmethod
    def get_current_turn_winner(game):
        """获取当前回合获胜者（用于平局情况）"""
        # 预留空间：应用平局相关的卡牌效果
        # TODO: 在这里应用平局相关的卡牌效果
        
        if game.current_turn % 2 == 1:
            return game.player1
        else:
            # AI对战时，AI获胜
            if game.player2 is None and game.player2_deck is not None:
                return None  # AI获胜时返回None
            else:
                return game.player2
    
    @staticmethod
    def check_game_end(game):
        """检查游戏是否结束"""
        finished_rounds = game.rounds.filter(is_finished=True).count()
        
        if finished_rounds >= game.max_rounds:
            # 游戏结束，计算最终获胜者
            player1_wins = game.rounds.filter(winner=game.player1).count()
            
            # AI对战时，AI获胜的回合winner为None
            if game.player2 is None and game.player2_deck is not None:
                # AI游戏：计算AI获胜回合数（winner为None的回合）
                player2_wins = game.rounds.filter(winner=None).count()
            else:
                # 普通游戏：计算player2获胜回合数
                player2_wins = game.rounds.filter(winner=game.player2).count()
            
            if player1_wins > player2_wins:
                game.winner = game.player1
            elif player2_wins > player1_wins:
                # AI对战时，AI获胜不设置winner（保持None）
                if game.player2 is None and game.player2_deck is not None:
                    game.winner = None  # AI获胜
                else:
                    game.winner = game.player2
            else:
                # 平局时，当前回合的玩家获胜
                if game.current_turn % 2 == 1:
                    game.winner = game.player1
                else:
                    # AI对战时，AI获胜
                    if game.player2 is None and game.player2_deck is not None:
                        game.winner = None
                    else:
                        game.winner = game.player2
            
            # 设置游戏为finished
            game.status = 'finished'
            game.finished_at = timezone.now()
            game.save()
            
            # 更新玩家战绩（只更新真实玩家的战绩）
            if game.winner is None and game.player2 is None and game.player2_deck is not None:
                # AI获胜，玩家失败
                game.player1.losses += 1
                game.player1.add_experience(50)  # 失败获得50经验
            elif game.winner == game.player1:
                # 玩家获胜
                game.player1.wins += 1
                game.player1.add_experience(100)  # 胜利获得100经验
            # 平局时不更新战绩
            
            return True  # 游戏结束
        
        return False  # 游戏继续
    
    @staticmethod
    def get_game_status(game):
        """获取游戏状态"""
        # 首先查找未完成的回合
        current_round = game.rounds.filter(is_finished=False).first()
        
        # 如果没有未完成的回合，返回最近完成的回合
        if not current_round:
            current_round = game.rounds.filter(is_finished=True).order_by('-round_number').first()
            
            # 如果没有任何回合，创建第一回合
            if not current_round and game.rounds.count() == 0:
                current_round = GameRound.objects.create(
                    game=game,
                    round_number=1
                )
        
        status = {
            'game_id': game.id,
            'status': game.status,
            'current_turn': game.current_turn,
            'player1': {
                'id': game.player1.id,
                'nickname': game.player1.nickname,
                'deck_name': game.player1_deck.name,
                'deck': {
                    'id': game.player1_deck.id,
                    'name': game.player1_deck.name,
                    'cards': [{'id': dc.card.id, 'name': dc.card.name, 'attack_power': dc.card.attack_power, 'star_level': dc.card.star_level, 'element': dc.card.element} for dc in game.player1_deck.deck_cards.all()]
                }
            },
            'player2': {
                'id': game.player2.id if game.player2 else None,
                'nickname': game.player2.nickname if game.player2 else 'AI对手',
                'deck_name': game.player2_deck.name if game.player2_deck else None,
                'deck': {
                    'id': game.player2_deck.id if game.player2_deck else None,
                    'name': game.player2_deck.name if game.player2_deck else 'AI卡组',
                    'cards': [{'id': dc.card.id, 'name': dc.card.name, 'attack_power': dc.card.attack_power, 'star_level': dc.card.star_level, 'element': dc.card.element} for dc in game.player2_deck.deck_cards.all()] if game.player2_deck else []
                }
            },
            'current_round': None,
            'rounds': []
        }
        
        if current_round:
            status['current_round'] = {
                'round_number': current_round.round_number,
                'player1_card': {
                    'id': current_round.player1_card.id,
                    'name': current_round.player1_card.name,
                    'attack_power': current_round.player1_card.attack_power,
                    'star_level': current_round.player1_card.star_level,
                    'element': current_round.player1_card.element
                } if current_round.player1_card else None,
                'player2_card': {
                    'id': current_round.player2_card.id,
                    'name': current_round.player2_card.name,
                    'attack_power': current_round.player2_card.attack_power,
                    'star_level': current_round.player2_card.star_level,
                    'element': current_round.player2_card.element
                } if current_round.player2_card else None,
                'is_finished': current_round.is_finished,
                'winner': {
                    'id': current_round.winner.id if current_round.winner else None,
                    'nickname': current_round.winner.nickname if current_round.winner else 'AI对手'
                } 
            }
        
        # 获取所有回合信息
        for round_obj in game.rounds.filter(is_finished=True):
            status['rounds'].append({
                'round_number': round_obj.round_number,
                'player1_card': {
                    'id': round_obj.player1_card.id,
                    'name': round_obj.player1_card.name,
                    'attack_power': round_obj.player1_card.attack_power,
                    'star_level': round_obj.player1_card.star_level,
                    'element': round_obj.player1_card.element
                },
                'player2_card': {
                    'id': round_obj.player2_card.id,
                    'name': round_obj.player2_card.name,
                    'attack_power': round_obj.player2_card.attack_power,
                    'star_level': round_obj.player2_card.star_level,
                    'element': round_obj.player2_card.element
                },
                'winner': {
                    'id': round_obj.winner.id,
                    'nickname': round_obj.winner.nickname
                } if round_obj.winner else None
            })
        
        # 设置游戏获胜者信息（只有在游戏结束时才设置）
        if game.winner is not None:
            # 玩家获胜
            status['winner'] = {
                'id': game.winner.id,
                'nickname': game.winner.nickname
            }
        elif game.winner is None and game.player2 is None and game.player2_deck is not None and game.rounds.filter(is_finished=True).count() >= game.max_rounds:
            # AI获胜（AI对战中winner为None表示AI获胜，且游戏已结束）
            status['winner'] = {
                'id': None,
                'nickname': 'AI对手'
            }
        elif game.status == 'finished' and game.winner is None:
            # 平局情况（普通对战中winner为None）
            status['winner'] = None
        
        return status
    
    @staticmethod
    def create_ai_deck():
        """创建AI固定卡组"""
        # 获取一些固定的卡牌作为AI卡组
        ai_cards = Card.objects.filter(is_active=True).order_by('?')[:5]
        
        if len(ai_cards) < 5:
            # 如果卡牌不足，创建一些默认卡牌
            ai_cards = []
            for i in range(5):
                card, created = Card.objects.get_or_create(
                    name=f'AI卡牌{i+1}',
                    defaults={
                        'description': f'AI专用卡牌{i+1}',
                        'attack_power': random.randint(1, 5),
                        'star_level': random.randint(1, 5),
                        'element': random.choice(['fire', 'water', 'wood', 'metal', 'earth']),
                        'rarity': 'common',
                        'cost': 0,
                        'is_active': True
                    }
                )
                ai_cards.append(card)
        
        # 创建AI卡组
        ai_deck = Deck(
            name='AI卡组',
            user=None,  # AI没有用户
            is_active=True
        )
        ai_deck.save()
        
        # 添加卡牌到AI卡组
        for card in ai_cards:
            deck_card = DeckCard(
                deck=ai_deck,
                card=card,
                quantity=1
            )
            deck_card.save()
        
        return ai_deck
    
    @staticmethod
    def ai_play_card(game, current_round):
        """AI出牌逻辑 - 固定顺序出牌"""
        if not game.player2_deck:
            return False, "AI没有卡组"
        
        # 获取AI卡组中的卡牌，按ID排序确保固定顺序
        ai_cards = game.player2_deck.deck_cards.all().order_by('card__id')
        if not ai_cards:
            return False, "AI卡组为空"
        
        # 获取当前回合数，用于确定AI出哪张牌
        round_index = (current_round.round_number - 1) % len(ai_cards)
        ai_card = ai_cards[round_index].card
        
        # 检查AI是否已经出过这张牌
        existing_action = PlayerAction.objects.filter(
            game=game,
            round=current_round,
            player=None,  # AI的player为None
            action_type='play_card'
        ).exists()
        
        if existing_action:
            return False, "AI已经出过牌了"
        
        # 记录AI行动
        PlayerAction.objects.create(
            game=game,
            round=current_round,
            player=None,  # AI没有用户
            action_type='play_card',
            card=ai_card
        )
        
        # 更新回合信息
        current_round.player2_card = ai_card
        current_round.save()
        
        return True, f"AI出牌: {ai_card.name}"
    
    @staticmethod
    def play_card_with_ai(game, player, card):
        """玩家出牌，然后AI自动出牌"""
        # 玩家出牌
        success, message = GameLogic.play_card(game, player, card)
        if not success:
            return False, message
        
        # 重新获取当前回合（因为play_card可能已经更新了回合）
        current_round = game.rounds.filter(is_finished=False).first()
        if not current_round:
            return False, "没有进行中的回合"
        
        # 注意：AI出牌现在由前端延迟1秒后触发，不再在这里立即出牌
        # 这样可以给玩家一些反应时间
        
        return True, "出牌成功，等待AI出牌"
